package me.firstapp.config;

import java.io.IOException;
import java.util.Properties;

import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;

import me.firstapp.common.utils.SpringContextTool;
import me.firstapp.spi.bbs.AdvertisementService;
import me.firstapp.spi.bbs.CollectionService;
import me.firstapp.spi.bbs.EmailService;
import me.firstapp.spi.bbs.MemberService;
import me.firstapp.spi.bbs.NotificationService;
import me.firstapp.spi.bbs.ReplyService;
import me.firstapp.spi.bbs.SearchService;
import me.firstapp.spi.bbs.SectionService;
import me.firstapp.spi.bbs.TopicService;
import me.firstapp.spi.shop.AddressService;
import me.firstapp.spi.shop.CategoryService;
import me.firstapp.spi.shop.OrderService;
import me.firstapp.spi.shop.PointService;
import me.firstapp.spi.shop.ProductCommentService;
import me.firstapp.spi.shop.ProductService;
import me.firstapp.spi.shop.ProductSkuRelService;
import me.firstapp.spi.shop.ShoppingCartService;
import me.firstapp.spi.shop.SkuService;

@Configuration
public class RootConfig {

	@Bean
	public PropertiesFactoryBean configProperties() {
		PropertiesFactoryBean configProperties = new PropertiesFactoryBean();
		configProperties.setLocations(new ClassPathResource("config.properties"));
		return configProperties;
	}

	@Bean
	public HttpInvokerProxyFactoryBean sectionService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/section.service");
			proxy.setServiceInterface(SectionService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean topicService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/topic.service");
			proxy.setServiceInterface(TopicService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean memberService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/member.service");
			proxy.setServiceInterface(MemberService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean addressService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/address.service");
			proxy.setServiceInterface(AddressService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean shoppingCartService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/shoppingCart.service");
			proxy.setServiceInterface(ShoppingCartService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean productService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/product.service");
			proxy.setServiceInterface(ProductService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean orderService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/order.service");
			proxy.setServiceInterface(OrderService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean notificationService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/notification.service");
			proxy.setServiceInterface(NotificationService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean skuService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/sku.service");
			proxy.setServiceInterface(SkuService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean collectionService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/collection.service");
			proxy.setServiceInterface(CollectionService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean emailService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/email.service");
			proxy.setServiceInterface(EmailService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean replyService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/reply.service");
			proxy.setServiceInterface(ReplyService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean categoryService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/category.service");
			proxy.setServiceInterface(CategoryService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean pointService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/point.service");
			proxy.setServiceInterface(PointService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean productSkuRelService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/productSkuRel.service");
			proxy.setServiceInterface(ProductSkuRelService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean productCommentService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/productComment.service");
			proxy.setServiceInterface(ProductCommentService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean advertisementService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/advertisement.service");
			proxy.setServiceInterface(AdvertisementService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	@Bean
	public HttpInvokerProxyFactoryBean searchService(PropertiesFactoryBean configProperties) {
		HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
		try {
			Properties properties = configProperties.getObject();
			proxy.setServiceUrl(properties.getProperty("spi.server.url") + "/search.service");
			proxy.setServiceInterface(SearchService.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}
	
	@Bean
	public RedisConnectionFactory redisCF(PropertiesFactoryBean configProperties) {
		JedisConnectionFactory cf = new JedisConnectionFactory();
		try {
			Properties properties = configProperties.getObject();
			cf.setHostName(properties.getProperty("redis.host"));
			cf.setPort(Integer.valueOf(properties.getProperty("redis.port", "6379")));
			cf.setPassword(properties.getProperty("redis.password"));

		} catch (IOException e) {
			e.printStackTrace();
		}
		return cf;
	}

	@Bean
	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisCF) {
		RedisTemplate<String, Object> redis = new RedisTemplate<>();
		redis.setConnectionFactory(redisCF);
		return redis;
	}

	@Bean
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisCF) {
		return new StringRedisTemplate(redisCF);
	}

	// ===============================其它=====================================
	@Bean
	public SpringContextTool springContextTool() {
		return new SpringContextTool();
	}

	// multipart请求
	@Bean
	public MultipartResolver multipartResolver() {
		return new StandardServletMultipartResolver();
	}
}
